package com.example.demo.rsa;

import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.openssl.PEMKeyPair;
import org.bouncycastle.openssl.PEMParser;
import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.util.Base64;

public class tEST2 {


    static {
        try {
            Security.addProvider(new BouncyCastleProvider());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    public static void main(String[] args) throws IOException, NoSuchPaddingException, NoSuchAlgorithmException, IllegalBlockSizeException, BadPaddingException, NoSuchProviderException, InvalidKeyException {

        String prviateKeyPem = "-----BEGIN RSA PRIVATE KEY-----\n" +
                "MIICXAIBAAKBgQCAWQ4eYPEvte+bS4KM1jWksKjR1+bHB4Lc8KL6WMNFFTpQaWie\n" +
                "Rb7/F7gbpRSnG/Xhg6VDsdpSGaGOJmCk7hN2mdWRl49dPTuNNC+PK8lK5nvmkhYz\n" +
                "I1u78y9Pym7RSPX+NGGc0yrqytbRzwKPIHcTlKQGUIUw6zr2sk1m1LzdmwIDAQAB\n" +
                "AoGAO6+uZig04TgdZj2WR4JyTdUtnPBnTNVMYQyy7fMLU/wMM0rhsQDEUoKoRord\n" +
                "cN0K2kXLPBDgc1+iBqYIOYrRl6KhYBGr/llNHhlCX4oRliZYFHRU+3z8dj0/5Ija\n" +
                "q/CJZWEA80jYDDUJ9QGXgROAaLiTl5c/8LpIOTrzQ5wWA/kCQQCdLNpp409IW13J\n" +
                "1LelsvDMDldTpgZX2PLqpwtHEj3R2qixhFW02HYheU8OfXXcVU8VHWHZeU+dXva2\n" +
                "EEnNDbcPAkEA0Qwc1QUzgEZF0qjI/Qs8utQDaMtqNLw85NUGz3ywq2alqroY3NOE\n" +
                "ke2zcOCZqkK+RACjr2eJ5Om4izLi286QtQJAHXLE7Wf4d88ekG05h2MyeJkLRZHq\n" +
                "yFTOlqZ7l3JUgNgeGTx5LmwMHhNze3yIM6MMMSGTLsLq5spfIReGLFQwgwJAaHBq\n" +
                "vyo4DrANFi/pKjLBBn4BrgtiZjJdId4j5ulewmMoBWGwJjMumlFtQsmTO/LYZ9UB\n" +
                "8hICXHFAF5s2p6ZNuQJBAI+cyQcPrxSoHn8rPg4CAHluLLqRxnK2jy7rexBCaHzU\n" +
                "ODKSstnaxGFL+NMIGn2GTce06QeUXlltpLPxxKecjRo=\n" +
                "-----END RSA PRIVATE KEY-----";

        String encryptRandomKey2 = "X0YhaVtw2AIn5oR7NefeNNndLXIP9F0W5OY1cON3R23qJLC6vDRlzg4R5hiJxzCG1PmUmjTiYwFQmrMPnTk4zkC3fdQxIzaDvmLVlUgogcecUkeCtbLafXnILxd0QMtqvAPz1PB4eee0ahRRur1yMGt90FAulKl3EPYld0q5RbA=";
        PrivateKey privateKeyObj = getPrivateKey(prviateKeyPem);
        String str = decryptRSA(encryptRandomKey2, privateKeyObj);
        System.out.println(str);

    }


    /**
     * RSA pkcs1 2048bit 解密工具,
     * 获取私钥PrivateKey
     *
     * @param privKeyPEM 2048bit pkcs1格式,base64编码后的RSA字符串
     * @return PrivateKey, 用于解密 decryptRSA
     * @throws IOException 异常
     */
    public static PrivateKey getPrivateKey(String privKeyPEM) throws IOException {
        PrivateKey privateKey = null;
        Reader privateKeyReader = new StringReader(privKeyPEM);
        PEMParser privatePemParser = new PEMParser(privateKeyReader);
        Object privateObject = privatePemParser.readObject();
        if (privateObject instanceof PEMKeyPair) {
            PEMKeyPair pemKeyPair = (PEMKeyPair) privateObject;
            JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider("BC");
            privateKey = converter.getPrivateKey(pemKeyPair.getPrivateKeyInfo());
        }
        return privateKey;
    }

    /**
     * RSA pkcs1 2048bit 解密工具,
     *
     * @param str        被解密的字符串
     * @param privateKey 私钥对象 从 getPrivateKey 获取
     * @return 解密后数据
     * @throws NoSuchPaddingException    异常
     * @throws NoSuchAlgorithmException  异常
     * @throws InvalidKeyException       异常
     * @throws BadPaddingException       异常
     * @throws IllegalBlockSizeException 异常
     */
    public static String decryptRSA(String str, PrivateKey privateKey) throws NoSuchPaddingException,
            NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException, NoSuchProviderException {
        Security.addProvider(new BouncyCastleProvider());
        Cipher rsa = Cipher.getInstance("RSA/ECB/PKCS1Padding", "BC");
        rsa.init(Cipher.DECRYPT_MODE, privateKey);
        byte[] utf8 = rsa.doFinal(Base64.getDecoder().decode(str));
        return new String(utf8, StandardCharsets.UTF_8);
    }
}
